#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/12/7 23:18
# @Author  : chenyj
# @File    : PythonOptimization.py
# @Software: IntelliJ IDEA
import abc
import timeit
from abc import ABCMeta, abstractmethod
import profile

class TestTraditionalAndGradeUsage(metaclass=ABCMeta):
    # Abstract method to return the Traditional way
    @abstractmethod
    def traditional(self):
        pass

    # Abstract method to return the Grade way
    @abstractmethod
    def grade_way(self):
        pass

    # Method to compare the performance of Traditional and Grade way
    def runtime_compare(self):
        # Create a TimeFunRun object for Traditional way
        time_run_traditional = TimeFunRun(f"{self.__name__}", "traditional")
        # Print the time taken by Traditional way
        time_run_traditional.print_time()
        # Create a TimeFunRun object for Grade way
        time_run_grade = TimeFunRun(f"{self.__name__}", "grade_way")
        # Print the time taken by Grade way
        time_run_grade.print_time()


class TimeFunRun:
    # Initialize the class with the class name and function name
    def __init__(self, classname: str, funname: str):
        # Store the function name with the setup code
        self.fun = funname + "()"
        # Store the function name
        self.funname = funname
        # Store the class name
        self.classname = classname

    # Print the time of the function
    def print_time(self):
        # Create a timer object with the setup code and the function name
        t = timeit.Timer(setup=f"from __main__ import {self.classname}", stmt=f"{self.classname}.{self.fun}")
        # Print the time of the function
        print(t.timeit())


class TestListComprehension(TestTraditionalAndGradeUsage):
    #Define a static method called traditional
    @staticmethod
    def traditional():
        #Create an empty list
        list_obj = []
        #Loop through the range 0 to 100
        for i in range(100):
            #Append the value of i to the list
            list_obj.append(i)

    #Define a static method called grade_way
    @staticmethod
    def grade_way():
        #Create a list comprehension that will loop through the range 0 to 100
        [i for i in range(100)]


class TestStrJoin(TestTraditionalAndGradeUsage):
    @staticmethod
    def traditional():
        obj = ["hello", "my", "name", "is", "john"]
        s = ""
        for ele in obj:
            s += ele

    @staticmethod
    def grade_way():
        obj = ["hello", "my", "name", "is", "john"]
        s = ""
        s.join(obj)


class TestForAndMap(TestTraditionalAndGradeUsage):
    @staticmethod
    def traditional():
        obj = ["hello", "my", "name", "is", "john"]
        for i in obj:
            i.upper()

    @staticmethod
    def grade_way():
        obj = ["hello", "my", "name", "is", "john"]
        map(str.upper, obj)


class RightDataStruct(TestTraditionalAndGradeUsage):
    @staticmethod
    def traditional():
        fruits = ["apple", "banana", "cherry"]
        "apple" in fruits
        "cherry" in fruits

    @staticmethod
    def grade_way():
        fruits = {"apple", "banana", "cherry"}
        "apple" in fruits
        "cherry" in fruits



if __name__ == '__main__':
    # TestListComprehension.runtime_compare(self=TestListComprehension)
    # print(f"{TestListComprehension.__name__}")
    TestStrJoin.runtime_compare(self=TestStrJoin)
    print(f"{TestStrJoin.__name__}")
    # 代码分析
    profile.run("TestStrJoin.traditional()")
    # 向量化
    # 用Cpython 编译，提高性能